﻿using System.Diagnostics;
using System.IO;
using System.Text;
using ExcelDataReader;

namespace ExcelToJson
{
    public class ClassGenerator
    {
        private string mExportPath = "";
        private PlatformType mPlatformType = PlatformType.None;

        private string className = string.Empty;
        private string[] mDescriptionArray;
        private string[] mFieldArray;
        private string[] mTypeArray;
        private string[] mPlatformArray;
        private StringBuilder stringBuilder = new StringBuilder();

        /// <summary>初始化</summary>
        /// <param name="pExportPath">导出路径</param>
        /// <param name="pPlatformType">平台类型</param>
        public void Init(string pExportPath, PlatformType pPlatformType)
        {
            mExportPath = pExportPath;
            mPlatformType = pPlatformType;

            if (!Directory.Exists(mExportPath))
            {
                Directory.CreateDirectory(mExportPath);
            }
        }

        /// <summary>生成脚本</summary>
        /// <param name="configPath">配置路径</param>
        public void GenerateScript(FileSystemInfo pFileSystemInfo)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            ParseConfig(pFileSystemInfo.FullName);

            if (CheckPlatform(mPlatformArray[0]))
            {
                int index = pFileSystemInfo.Name.IndexOf(".");
                className = pFileSystemInfo.Name.Substring(0, index);
                GenerateCode();
                ExportFile();
            }
        }

        /// <summary>解析配置</summary>
        /// <param name="configPath">配置路径</param>
        private void ParseConfig(string pConfigPath)
        {
            FileStream stream = File.OpenRead(pConfigPath);
            IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);

            while (excelReader.Read())
            {
                if (excelReader.Depth == (int)EnumExcelStruct.Description)
                {
                    mDescriptionArray = GetDatas(excelReader);
                }
                else if (excelReader.Depth == (int)EnumExcelStruct.Field)
                {
                    mFieldArray = GetDatas(excelReader);
                }
                else if (excelReader.Depth == (int)EnumExcelStruct.Type)
                {
                    mTypeArray = GetDatas(excelReader);
                }
                else if (excelReader.Depth == (int)EnumExcelStruct.Platform)
                {
                    mPlatformArray = GetDatas(excelReader);
                }
                else
                {
                    break;
                }
            }
            excelReader.Close();
        }

        /// <summary>获取数据</summary>
        /// <param name="excelReader">excelReader</param>
        private string[] GetDatas(IExcelDataReader excelReader)
        {
            string[] datas = new string[excelReader.FieldCount];
            for (int i = 0; i < excelReader.FieldCount; i++)
            {
                datas[i] = excelReader.GetString(i);
            }

            return datas;
        }

        private bool CheckPlatform(string pPlatformKey)
        {
            if (mPlatformType == PlatformType.Client && (pPlatformKey == PlatformDefine.cCSKey || pPlatformKey == PlatformDefine.cCKey))
                return true;
            else if (mPlatformType == PlatformType.Server && (pPlatformKey == PlatformDefine.cCSKey || pPlatformKey == PlatformDefine.cSKey))
                return true;
            else
                return false;
        }

        /// <summary>生成代码</summary>
        private void GenerateCode()
        {
            stringBuilder.Clear();
            stringBuilder.Append("/*Auto-create script.\n");
            stringBuilder.Append(" * Don't Edit it. */\n");
            stringBuilder.Append("\n");
            stringBuilder.Append("using System.Collections.Generic;\n");
            stringBuilder.Append("using Framework.Data.Config;\n");
            stringBuilder.Append("\n");
            stringBuilder.Append("namespace Game.Data.Config\n");
            stringBuilder.Append("{\n");
            stringBuilder.AppendFormat("\tpublic class {0} : ConfigBase\n", className);
            stringBuilder.Append("\t{\n");

            for (int i = 0; i < mDescriptionArray.Length; i++)
            {
                if (CheckPlatform(mPlatformArray[i]) && i != 0)
                {
                    stringBuilder.AppendFormat("\t\t/// <summary>{0}</summary>\n", mDescriptionArray[i]);
                    stringBuilder.AppendFormat("\t\tpublic {0} {1};\n", mTypeArray[i], mFieldArray[i]);
                }
            }

            stringBuilder.Append("\t}\n");
            stringBuilder.Append("}");
        }

        /// <summary>输出文件</summary>
        private void ExportFile()
        {
            string path = string.Format("{0}/{1}.cs", mExportPath, className);
            string content = stringBuilder.ToString();
            File.WriteAllText(path, content);
        }
    }
}